﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HerGoS.Viaticos.Entities;
using HerGoS.DAO;
using HerGoS.Interfaces;
using System.Data;
using HerGoS.Viaticos.Exceptions;
using HerGoS.Administration.Entities;
using HerGoS.Administration.Engine;

namespace HerGoS.Viaticos.Engine
{
   public class GestorRendicion
    {
       public static Rendicion Obtener(int OID)
       {
           try
           {
               IRepository repo = RepositoryFactory.Create(Config.RepositoryViaticosName);
               repo.Nombre = "RENDICIONES_SP";
               repo.AddParameter("@ACCION", "BYID");
               repo.AddParameter("@ID", OID);
               DataTable dt = repo.ExecuteDataTable();
               Rendicion result = dt.ToGenericList<Rendicion>(RendicionConverter).FirstOrDefault();
               return result;
           }
           catch (Exception ex)
           {
               throw new RendicionGetException(ex);
           }
       }

       public static void Guardar(Rendicion rendicion)
       {
           try
           {
               IRepository repo = RepositoryFactory.CreateTransactional(Config.RepositoryViaticosName);
               repo.Nombre = "RENDICIONES_PROC";
               repo.AddParameter("@ACCION ", rendicion.Persistencia);
               repo.AddParameter("@ID", rendicion.OID);
               repo.AddParameter("@NUMERO", rendicion.NumeroRendicion);
               repo.AddParameter("@IDSOLICITUD", rendicion.SolicitudRendida == null ? (int?)null : rendicion.SolicitudRendida.OID);
               repo.AddParameter("@FECHA", rendicion.FechaRendicion);
               repo.AddParameter("@DISTANCIA", rendicion.Distancia == null ? (int?) null : rendicion.Distancia.OID);
               repo.AddParameter("@IDENTIDAD", rendicion.Entidad == null ? (int?)null : rendicion.Entidad.OID);
               repo.AddParameter("@IDAREA", rendicion.Area == null ? (int?)null : rendicion.Area.OID);
               repo.AddParameter("@IDPERSONA", rendicion.Persona == null ? (int?)null : rendicion.Persona.OID);
               repo.AddParameter("@FECHASALIDA", rendicion.FechaSalida);
               repo.AddParameter("@FECHARETORNO", rendicion.FechaRetorno);
               repo.AddParameter("@OBSERVACIONES", rendicion.Observaciones);
               repo.AddParameter("@OBJETIVOVIAJE", rendicion.ObjetivoViaje);
               repo.AddParameter("@IDUSUARIO", HGSContext.Usuario.OID);
               rendicion.OID = repo.ExecuteReturnValue().ToInteger();
               repo.Commit();


               GestorBitacora.Guardar(rendicion);

             GestorTramo.Guardar(rendicion);


           }
           catch (Exception ex)
           {
               throw new SolicitudSaveException(ex);
           }
       }

       public static void Eliminar(Rendicion rendicion)
       {
           rendicion.Persistencia = EstadoPersistencia.DELETE;
           Guardar(rendicion);
           rendicion.Persistencia = EstadoPersistencia.UPDATE;
           rendicion.Activo = false;
       }


       public static void ReActivar(Rendicion rendicion)
       {
           rendicion.Persistencia = EstadoPersistencia.UNDELETE;
           Guardar(rendicion);
           rendicion.Persistencia = EstadoPersistencia.UPDATE;
           rendicion.Activo = true;
       }

       public static List<Rendicion> Consultar(Rendicion rendicion)
       {
           try
           {
               IRepository repo = RepositoryFactory.Create(Config.RepositoryViaticosName);
               repo.Nombre = "RENDICIONES_SP";
               repo.AddParameter("@ACCION", "CONSULTA");
               repo.AddParameter("@ID", null);
               repo.AddParameter("@ACTIVO", rendicion.Activo);
               repo.AddParameter("@IDUSUARIO", HGSContext.Usuario.OID);
               DataTable dt = repo.ExecuteDataTable();
               List<Rendicion> result = dt.ToGenericList<Rendicion>(RendicionConverter);
               return result;

           }
           catch (Exception ex)
           {
               throw new SolicitudGetException(ex);
           }
       }

       public static List<Rendicion> Consultar()
       {
           return Consultar(new Rendicion { Activo = true });
       }

       public static List<Rendicion> RendicionesSinLiquidacion()
       {
           try
           {
               IRepository repo = RepositoryFactory.Create(Config.RepositoryViaticosName);
               repo.Nombre = "RENDICIONES_SP";
               repo.AddParameter("@ACCION", "RENDICIONESSINLIQ");
               repo.AddParameter("@ID", null);
               repo.AddParameter("@ACTIVO", true);
               repo.AddParameter("@IDUSUARIO", HGSContext.Usuario.OID);
               DataTable dt = repo.ExecuteDataTable();
               List<Rendicion> result = dt.ToGenericList<Rendicion>(RendicionConverter);
               return result;

           }
           catch (Exception ex)
           {
               throw new SolicitudGetException(ex);
           }
       }

       public static bool RendicionTieneLiquidacion(Rendicion rendicion)
       {
           try
           {
               IRepository repo = RepositoryFactory.Create(Config.RepositoryViaticosName);
               repo.Nombre = "RENDICIONES_SP";
               repo.AddParameter("@ACCION", "TIENELIQ");
               repo.AddParameter("@ID", rendicion.OID);
               repo.AddParameter("@ACTIVO", true);
               int count = repo.ExecuteScalar().ToInteger();

               return (count > 0); // si es > 0 tiene liquidacion asociada

           }
           catch (Exception ex)
           {
               throw new SolicitudGetException(ex);
           }
          
       
       }



       #region Converter

       public static Rendicion RendicionConverter(DataRow row)
       {
           Rendicion rendicion = new Rendicion
           {
               OID = row["rendID"].ToInteger(),
               Persistencia = EstadoPersistencia.UPDATE,
               NumeroRendicion = row["rendNUMERO"].ToInteger(),
               FechaRendicion = row["rendFECHA"].ToNullableDateTime(),
               SolicitudRendida = GestorSolicitudes.Obtener(row["rendIDSOLICITUD"].ToInteger()),
               Distancia = GestorDistancia.Obtener(row["renDistancia"].ToInteger()) ?? null,
               Entidad = GestorEntidades.Obtener(row["rendIDENTIDAD"].ToInteger()) ?? null,
               Area = GestorArea.Obtener(row["rendIDAREA"].ToInteger()) ?? null,
               Persona = GestorPersona.Obtener(row["rendIDPERSONA"].ToInteger()),
               FechaSalida = row["rendFECHASALIDA"].ToDateTime(),
               FechaRetorno = row["rendFECHARETORNO"].ToDateTime(),
               Observaciones = row["rendOBSERVACIONES"].ToString(),
               ObjetivoViaje = row["rendOBJETIVOVIAJE"].ToString(),

               Activo = row.IsNull("FECHA_BAJA") ? true : false
           };

           rendicion.Tramos = GestorTramo.Consultar(rendicion);
           return rendicion;
       }
       #endregion
    }
}
